package com.qianxun.watchdog.jar;

import com.qianxun.framework.util.FileUtil;
import com.qianxun.watchdog.script.ScriptExecutor;

import java.io.File;
import java.io.IOException;
import java.util.Set;

/**
 * 看门狗jar生成器
 * @author: huwei
 * @date: 2020/10/15 13:37
 * @version: 1.0.0
 */
public class JarGenerator {
    /**
     * JAVA 应用文件目录
     */
    private static final String JAVA_FILE_PATH;
    /**
     * JAVA 应用文件classpath 目录
     */
    private static final String JAVA_FILE_CLASS_PATH;
    /**
     * 存放根路径
     */
    private static final String SAVE_ROOT;
    static{
        //路径初始化
        JAVA_FILE_PATH = FileUtil.switchSeparator(JarGenerator.class.getName().replace(".",FileUtil.SEPARATOR).replace(JarGenerator.class.getSimpleName(),"") + "template" + FileUtil.SEPARATOR);
        JAVA_FILE_CLASS_PATH = "classpath:" + JAVA_FILE_PATH;
        SAVE_ROOT = FileUtil.switchSeparator(new File("/application/monitor/monitor-watchdog/").getAbsolutePath() + FileUtil.SEPARATOR);
    }
    {
        File root = new File(SAVE_ROOT);
        if(root.exists()){
            root.delete();
        }
        root.mkdirs();
    }

    /**
     * 启动看门狗
     * @throws Exception
     */
    public void startup() throws Exception {
        //应用文件绝对路径记录文件，用于在编译时的批量编译
        final File javaSources = new File(compileSourcePath());
        if(!javaSources.exists()){
            try {
                javaSources.createNewFile();
            }catch (Exception e){}
        }
        //读取模板目录文件下的应用的原文件
        Set<String> javaTmpFileSet = FileUtil.fileListAsRecursion(JAVA_FILE_CLASS_PATH ,(absPath, relativePath, fileName) -> fileName.endsWith(".tmp"));
        //将tmp文件转换成java源文件
        javaTmpFileSet.forEach(javaTmpFileAbsPath->{
            //java文件在其自身所构建的应用中的相对路径
            String javaTmpFilePathInSelfApp = javaTmpFileAbsPath.substring(javaTmpFileAbsPath.indexOf(JAVA_FILE_PATH) + JAVA_FILE_PATH.length());
            //目录创建
            if(javaTmpFilePathInSelfApp.lastIndexOf(FileUtil.SEPARATOR) != -1){
                String javaFileDirInSelfApp = javaTmpFilePathInSelfApp.substring(0 ,javaTmpFilePathInSelfApp.lastIndexOf(FileUtil.SEPARATOR));
                File dir = new File(SAVE_ROOT + javaFileDirInSelfApp);
                if(!dir.exists()){
                    dir.mkdirs();
                }
            }
            //java文件名称，替换掉.tmp后缀
            String javaFilePathInSelfApp = javaTmpFilePathInSelfApp.replace(".tmp" ,"");
            try {
                //内容读取
                byte[] buf = FileUtil.read(javaTmpFileAbsPath);
                //内容存入
                String savePath = SAVE_ROOT + javaFilePathInSelfApp;
                FileUtil.write(savePath ,buf);
                //源文件记录
                if(savePath.endsWith(".java")) {
                    FileUtil.write(javaSources, (savePath + "\r\n").getBytes(), true);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        });

        //创建名执行编译和运行脚本
        createAndExecuteScript();
    }

    public boolean isStartup(){
        String script = "ps -ef | grep "+watchdogJarName()+".jar | grep -v grep | head -n 1 | awk '{print $2}'";
        try {
            byte[] bytes = ScriptExecutor.getInstance().run(script);
            if(bytes != null && bytes.length > 0){
                String pidString = new String(bytes);
                try{
                    Integer.parseInt(pidString.trim());
                    return true;
                }catch (Exception e){
                }
            }
        } catch (Exception e) {
            return false;
        }
        return false;
    }

    private void createAndExecuteScript() throws Exception {
        //jar 编译和执行
        StringBuffer script = new StringBuffer();
        script.append("cd " + SAVE_ROOT).append("\n");
        script.append("java -version ").append("\n");
        script.append("echo \"compile original files \"").append("\n");
        script.append("javac @" + compileSourcePath()).append("\n");
        script.append("jar -cvfm ").append(watchdogJarName()).append(".jar").append(" MANIFEST.MF -C " + SAVE_ROOT + " .").append("\n");
        script.append("nohup java -jar " + SAVE_ROOT + watchdogJarName() + ".jar > "+SAVE_ROOT+"console.log &\n");

        //
        FileUtil.write(SAVE_ROOT + "go.sh" ,script.toString().getBytes());

        //go.sh脚本执行权限
        String run = "/bin/chmod 755 " + SAVE_ROOT + "go.sh \n " +
                " /bin/sh " + SAVE_ROOT + "go.sh" ;
        byte[] bytes = ScriptExecutor.getInstance().run(run);
        System.out.println(new String(bytes ,"gb2312"));
    }

    private String watchdogJarName(){
        return "monitor-watchdog";
    }

    private String compileSourcePath(){
        return SAVE_ROOT + "sources.txt";
    }
}
